AWS Client VPN の OpenVPN 設定ファイルの内訳を確認してみた
コンバンハ、千葉(幸)です。
AWS Client VPN では、OpenVPN ベースのクライアントを使用できます。
クライアントのセットアップの一環として「プロファイル」を作成する際には、VPN クライアント設定ファイルを読み込ませます。この設定ファイルは、AWS マネジメントコンソールからダウンロードしたものを使用するのが一般的です。この設定ファイルも OpenVPN ベースです。
特に OpenVPN に詳しくなくても AWS Client VPN のセットアップに困ることはないのですが、ふとしたときに設定ファイルを眺めることがありました。
それぞれの設定値の意味を確認したいとき、AWS ドキュメントではなく OpenVPN 関連のマニュアルを参照する必要があります。
せっかくなので調べた内容をこのブログにまとめておきます。
OpenVPN 設定ファイルのマニュアル
設定項目の意味を調べたいとき、まずは OpenVPN の公式のマニュアルを確認すると良いでしょう。
↑ここでは2023/8時点で最新の OpenVPN 2.6 マニュアルを参照しています。ページ内のリンクから他のバージョンのリファレンスに遷移できます。
OpenVPN をコマンドラインで実行する際の--
付きの形式で書かれていますが、設定ファイルに記述する際は--
を除去できる、と記載があります。
Though all command line options are preceded by a double-leading-dash ("--"), this prefix can be removed when an option is placed in a configuration file.
また、OpenVPN のクライアント側の設定ファイルのサンプルは以下にあります。コメント付きで記述されているので参考になります。
今回のブログでは、上記2つのソースを参考に内容を記述しています。
OpenVPN 設定ファイルのベーシックな設定項目
AWS Client VPN エンドポイントの設定値等によって細かい部分は変わりますが、AWS マネジメントコンソールからダウンロードした VPN 設定ファイルのサンプルは以下です。
client dev tun proto udp remote cvpn-endpoint-xxxxxxxxxxxxx.prod.clientvpn.ap-northeast-1.amazonaws.com 443 remote-random-hostname resolv-retry infinite nobind remote-cert-tls server cipher AES-256-GCM verb 3 <ca> -----BEGIN CERTIFICATE----- (ACMにインポートされたサーバー証明書の中身) -----END CERTIFICATE----- </ca> auth-user-pass reneg-sec 0 verify-x509-name server name
まずはこれらの内容について簡単に押さえます。
以降、表で「サーバー」という時には AWS Client VPN エンドポイントのことを指します。
項目名 | 引数例 | 概要 |
---|---|---|
client | なし | クライアント側の設定ファイルであることの宣言 |
dev | tun | デバイスの設定(TUN or TAP) |
proto | udp | サーバーとの接続に用いるプロトコル(UDP or TCP) |
remote | cvpn-endpoint-xxxxxxxxxxxxx.prod.clientvpn.ap-northeast-1.amazonaws.com 443 | サーバーのDNS名、ポート |
remote-random-hostname | なし | DNSキャッシュを防ぐためリモートホスト名にランダムな文字列を付与する |
resolv-retry | infinite | サーバーのDNS名の名前解決に失敗した際のリトライする秒数 |
nobind | なし | 指定するとローカルポート番号をバインドしない(動的割り当て) |
remote-cert-tls | server | サーバー証明書がRFC3280 TLS に基づいて署名されていることを要求 |
cipher | AES-256-CBC | 暗号方式の選択 |
verb | 3 | ログレベルを0~11で指定。verbosity。 |
ca | なし(証明書の内容が<ca></ca>に挟まれて記述されている) | サーバー証明書 |
auth-user-pass | なし | サーバーでユーザー名とパスワードでの認証を実施 |
reneg-sec | 0 | データチャネルキーの再ネゴシエーションまでの秒数 |
verify-x509-name | server name | サーバー証明書のコモンネームなどを検証 |
設定項目について補足
いくつかピックアップして補足説明します。
dev
TUN/TAPのいずれかを選択します。
TUN/TAPは仮想ネットワークデバイス及びそのデバイスドライバの実装およびデバイス名で、主にUnix系のシステムで利用できる。実ハードウェアであるネットワークカードと対応しているデバイスドライバと同様にネットワーク通信ができるが、データはハードウェアではなく、ネットワーク通信を仮想化したソフトウェアのプロセスに送られ、そこで処理される(例えば、VPNの相手方への通信として、改めて実ハードから送信される)。
TUN はネットワーク層、TAP はデータリンク層をシミュレートします。
AWS Client VPN の機能を考えると、 TUN のみがサポートされていると考えるのが自然です。
cipher
OpneVPN 2.4.0 より前はこのオプションが有効でしたが、2.4.0 以降は無視され、AES-256-GCM が使用されるとのことです。
AWS Client VPN が OpenVPN のどのバージョンに対応しているのか、の情報は見つけられませんでした。
ca
AWS Client VPN においては、VPN エンドポイントに関連づけた ACM のサーバー証明書の内容が埋め込まれています。
以下のようにファイルパスを指定する書き方もできます。
ca ca.crt
クライアント証明書を用いる際には、同じように以下の書き方ができます。
cert client.crt #クライアント証明書 key client.key #クライアント証明書のプライベートキー
逆に、cert
、key
ともに以下のように書くこともできます。
<cert> -----BEGIN CERTIFICATE----- (クライアント証明書の中身) -----END CERTIFICATE----- </cert> <key> -----BEGIN PRIVATE KEY----- (プライベートキーの中身) -----END PRIVATE KEY----- </key>
reneg-sec
VPN 接続においてデータチャネルは定期的にローテーションされる一時的な暗号化キーを使用します。
reneg-ssec
は再ネゴシエートするまでの秒数を定義する項目ですが、0
の場合は対向(ここではサーバー=VPNエンドポイント)の設定に依存します。
verify-x509-name
verify-x509-name 名称 タイプ
の構文で指定します。今回の例ではサーバー証明書のコモンネームがserver
です。タイプがname
の場合、デフォルトでコモンネームの検証を行います。
AWS VPN クライアントでサポートされている OpenVPN ディレクティブ
AWS 製の VPN クライアントツール(以降は AWS VPN クライアントと呼称)では、サポートされている OpenVPN ディレクティブがドキュメントに記載されています。
- auth-user-pass
- ca
- cert
- cipher
- client
- connect-retry
- cryptoapicert (Windows のみ)
- dev
- key
- nobind
- persist-key
- persist-tun
- proto
- remote
- remote-cert-tls
- remote-random-hostname
- reneg-sec
- resolv-retry
- static-challenge
- tun-mtu
- tun-mtu-extra
- verb
先ほどの表で取り上げていないものがあるため、補足します。
項目名 | 引数例 | 概要 |
---|---|---|
cert | client.crt | クライアント証明書 |
connect-retry | 3 | 接続試行の間隔の秒数 |
cryptoapicert (Windows のみ) | "SUBJ:client1.domain.tld" | Windows 証明書システム ストアから証明書と秘密キーをロード |
key | client.key | クライアント証明書用プライベートキー |
persist-key | なし | SIGUSR1による再起動時にキーファイルを読み込み直さない |
persist-tun | なし | SIGUSR1による再起動時にTUN/TAPデバイスをクローズしない |
static-challenge | "Please enter token PIN" 1 | static challenge/response protocolを有効にする |
tun-mtu | 1500 | TUNデバイスのMTU(最大伝送単位) |
tun-mtu-extra | 32 | tun-mtuを超えて返すサイズの想定 |
設定項目について補足
一部を補足説明します。
persist-key
SIGUSR1
による OpenVPN プロセス再起動時にキーファイルを読み込み直さないためのオプションです。
SIGUSR1
とは OpenVPN に送られるシグナルの一つで、 root権限なしでプロセスを再起動する条件付き再起動を指します。--ping-restart
によってトリガーされることもあります。(一定期間Pingの応答がなかったら再起動)
static-challenge
静的な Challenge/Response Protocol を使用するためのオプションです。例えば接続するユーザーにPINコードを入力させるようなことができます。
以下の構文がサポートされています。
static-challenge text echo
text
にはユーザーに表示したいメッセージを、echo
では入力した内容を表示する(1
)かしない(0
)かを定義します。
AWS VPN クライアントでサポートされている OpenVPN フラグ
上記の「サポートされている OpenVPN ディレクティブ」に記述がないものでも、いくつかの機能は AWS VPN クライアントで対応しています。それはリリースノートで確認できます。
例えば Windows 向けクライアントのリリースノートは以下です。
多くは「OpenVPN フラグ」という表現がされています。(route-ipv6
は OpenVPN ディレクティブであるものの、リリースノートにしか記述がない。)
リリースノートで確認できる項目のうち、ここまで取り上げなかったものをまとめます。
項目名 | 引数例 | 概要 |
---|---|---|
route-ipv6 | 2001:db8:0:abc::/64 | IPv6のルートをプッシュ |
inactive | 30 | 指定した秒数 非アクティブな時にVPNを終了 |
pull-filter | ignore "route" | サーバー側からの設定のプッシュをフィルタリングする |
route | 10.0.0.0 255.0.0.0 | IPv4のルートをプッシュ |
dhcp-option | DNS 8.8.8.8 | DHCP関連の設定をプッシュ |
connect-retry-max | 3 | 接続リトライの試行回数 |
dev-type | tun | デバイスタイプ(TUN or TAP) |
keepalive | 10 60 | pingオプションのインターバルとタイムアウト |
ping | 10 | 指定した秒数パケットが送信されない場合pingを実行 |
ping-restart | 120 | 指定した秒数パケットやpingが送信されない場合SIGUSR1による再起動 |
pull | なし | サーバーからのプッシュを受け入れる |
rcvbuf | 0 | TCP/UDP ソケットの受信バッファサイズ |
server-poll-timeout | 120 | サーバーからの応答を待つ最大秒数 |
設定項目の補足
ここでもいくつか取り上げます。
inactive
inactvie 秒数 バイト
のように書くこともできます。
その場合、「指定した秒数内のトラフィック量が指定したバイト数未満の場合に VPN 接続を終了」という挙動になります。
pull-filter
以下の構文がサポートされています。
pull-filter accept text pull-filter ignore text pull-filter reject text
text
にはサーバー側からプッシュされるオプション名が入ります。例えばroute
やdhcp-option
です。
accept
:受け入れるignore
:受け入れないreject
:受け入れず、SIGUSR1
による再起動を実施
AWS Client VPN エンドポイントで指定した DNS サーバーや Client VPN ルートテーブルの内容は VPN 接続時にクライアントにプッシュされてきますが、このオプションを使うことでフィルタリングできそうです。
route
以下の構文がサポートされています。
route network/IP route network/IP netmask route network/IP netmask gateway route network/IP netmask gateway metric
クライアント側で制御するよりはサーバーからプッシュされたルートをそのまま受け入れた方が複雑にならなくていいとは思います。
dhcp-options
dhcp-options タイプ パラメーター
の構文で指定します。
タイプは、DNS
だけでなくNTP
やDOMAIN
、WIN
など多くのものが対応しています。
dev-type
dev
で指定するデバイス名がtun
もしくはtap
で始まらない場合のみこのオプションで指定します。
AWS Client VPN で使う機会はあまりなさそうです。
ping
一定期間パケットが送信されなかった場合に、TCP/UDP 制御チャネル経由でリモート(ここではサーバー)に ping を送信します。(IP Ping パケットではない。)
定期的な ping により、OpenVPN 接続のための UDP パケットを許可するステートフルファイアウォールのタイムアウトを避けられます。
pull
サーバーからのオプションのプッシュを受け入れることを示すオプションです。
client
ディレクティブによって暗黙的にpull
相当の指定がなされているはずなので、あえて書く場面がわかっていません。
AWS VPN クライアントでサポートされていない設定項目
ここまでいくつか AWS VPN クライアントに焦点を絞って確認してきましたが、「AWS VPN クライアントではサポートされていないが AWS Client VPN で使用できる」項目もあります。
例えば以下エントリではhttp-proxy
OpneVPN ディレクティブを使用しています。
使いたい機能がある場合は、OpenVPN のマニュアルから探してみるのもよいでしょう。
なお、AWS VPN クライアントでサポートされていない機能を用いる場合は、「OpneVPN クライアント」など、別のクライアントツールを用いる必要があります。
サポートされていないディレクティブが含まれる設定ファイルを読み込ませると?
AWS VPN クライアントでサポートされていないディレクティブを含む VPN 設定ファイルを用いてプロファイルを作成しようとすると、以下のようなエラーが出ます。(Windows向けの場合の例。)
OpenVPN 設定の行「xxxx」には、サポートされていないディレクティブが含まれています。それを OpneVPN 設定から削除します。
全部が全部ダメなわけじゃない?
以下の設定項目を持つ VPN 設定ファイルを用いて AWS VPN クライアントでプロファイルを作成したところ、問題なく成功しました。
auth-federate auth-retry interact auth-nocache
上記の項目(ディレクティブ)は、「サポートされているディレクティブ」の一覧に載っていません。この状況をどう捉えるのがよいのか分かりませんが、ドキュメントでの確認に留めず実機で検証するのが一番確実そうです。
終わりに
AWS Client VPN のクライアントに用いる OpenVPN 設定ファイルの内訳を確認してみました。
改めて考えると、AWS Client VPN とは「マネージドな OpenVPN サーバー」であると感じました。
例えば EC2 インスタンスを立ててそこで OpenVPN サーバーを起動させる、でも AWS Client VPN と近しいことはできるはずです。(あるいはもっと細やかな制御ができる。)
とはいえそこの OS 管理をするのは大変ですし、設定項目もだいぶ複雑です。AWS Client VPN を利用することでマネージドになり、設定も抽象化された形で取り扱えます。
AWS Client VPN を活用しつつ、細かい部分でカスタマイズが必要な場合は OpenVPN のマニュアルを確認してみてください。
以上、 チバユキ (@batchicchi) がお送りしました。
参考
- How To | OpenVPN.JP
- How To Guide: Set Up & Configure OpenVPN Client/server VPN | OpenVPN
- openvpn/doc/management-notes.txt at master · OpenVPN/openvpn
- Client VPN の証明書を Windows で作成してみた (vpnux PKI Manager 編) | DevelopersIO
- AWS VPN Client(AWS Client VPN for Desktop)でプロファイル追加する際に OpenVPN 設定 verify-x509-name 関連のエラーが発生した時の対処方法 | DevelopersIO